import 'dart:async';
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:hc_bio_sdk/model/heart_rate.dart';
import 'package:hc_bio_sdk/model/hrv.dart';
import 'package:hc_bio_sdk/model/mind_read_result.dart';
import 'package:hc_bio_sdk/model/rr.dart';
import 'package:hc_bio_sdk/model/wave.dart';

import 'hc_bio_sdk_platform_interface.dart';
import 'model/main_Indicator.dart';

/// An implementation of [HcBioSdkPlatform] that uses method channels.
class MethodChannelHcBioSdk extends HcBioSdkPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('hc_bio_sdk');

  MethodChannelHcBioSdk() {
    methodChannel.setMethodCallHandler((call) async {
      if (call.method == "onReceiveBioData") {
        final type = call.arguments["type"] as String;
        final value = call.arguments["value"] as String;
        final json = jsonDecode(value);

        switch (type) {
          case "HRV":
            final model = HRV.fromJson(json);
            dataStream.sink.add(model);
            break;
          case "HeartRate":
            final model = HeartRate.fromJson(json);
            dataStream.sink.add(model);
            break;
          case "MainIndicator":
            final key = (json as Map<String, dynamic>).keys.first;
            final value = json[key];
            final model = MainIndicator(key, value);
            dataStream.sink.add(model);
            break;
          case "MindRead":
            final model = MindReadResult.fromJson(json);
            dataStream.sink.add(model);
            break;
          case "Wave":
            final model = Wave.fromJson(json);
            dataStream.sink.add(model);
            break;
          default:
            break;
        }
      }
    });
  }

  @override
  Future<String?> getPlatformVersion() async {
    final version =
        await methodChannel.invokeMethod<String>('getPlatformVersion');
    return version;
  }

  @override
  Future append(RRModel rr) async {
    await methodChannel.invokeMethod(
      'append',
      rr.toJson(),
    );
  }

  @override
  Future initialize(String channelCode) async {
    await methodChannel.invokeMethod(
      'initialize',
      {"channelCode": channelCode},
    );
  }

  @override
  Future login({required String userID}) async {
    await methodChannel.invokeMethod("login", userID);
  }
}
